from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import MultiPartParser, JSONParser
from django.core.paginator import Paginator
from .models import *
import logging
from rest_framework.decorators import action
from datetime import datetime, timedelta
from utils.pagination import MyPageNumberPagination
from django.core.exceptions import ObjectDoesNotExist
from django.utils import timezone


logger = logging.getLogger(__name__)


class BaseOrderViewSet(viewsets.ModelViewSet):
    """
    订单视图集的基类，提供通用的CRUD操作和错误处理
    """
    permission_classes = [IsAuthenticated]
    parser_classes = (MultiPartParser, JSONParser)
    lookup_field = 'id'  # 默认使用id作为查找字段
    pagination_class = MyPageNumberPagination

    def handle_error(self, error, operation='操作'):
        """通用的错误处理方法"""
        error_message = str(error)
        logger.error(f"{operation}失败: {error_message}")
        return Response({'code': 400, 'message': f'{operation}失败: {error_message}'}, status=status.HTTP_400_BAD_REQUEST)
    
    def get_optimized_queryset(self):
        """
        获取优化后的查询集，添加select_related和prefetch_related
        """
        queryset = super().get_queryset()
        # 预加载创建用户信息，避免在序列化时重复查询用户表
        queryset = queryset.select_related('created_by')
        # 如果有其他外键关系，可以在子类中重写此方法添加更多select_related
        # 例如：queryset = queryset.select_related('created_by', 'updated_by', 'category')
        # 添加排序优化，使用数据库索引
        queryset = queryset.order_by('-create_time')
        return queryset
    
    def get_queryset(self):
        """
        获取查询集并应用过滤条件
        """
        # 使用优化后的查询集
        queryset = self.get_optimized_queryset()
        
        # 处理日期范围查询
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if start_date and end_date:
            try:
                # 将日期字符串转换为datetime对象
                start_date = datetime.strptime(start_date, '%Y-%m-%d')
                end_date = datetime.strptime(end_date, '%Y-%m-%d')
                # 将end_date加1天，以包含当天的所有数据
                end_date = end_date + timedelta(days=1)
                # 转换为带时区的datetime
                start_date = timezone.make_aware(start_date)
                end_date = timezone.make_aware(end_date)
                
                queryset = queryset.filter(create_time__range=[start_date, end_date])
            except ValueError:
                pass
        
        return queryset

    def list(self, request, *args, **kwargs):
        """
        获取订单列表（已优化查询性能）
        """
        try:
            # 获取查询参数
            keyword = request.query_params.get('keyword', '') # 搜索关键词 fs_no, cs_no, cw_no等
            is_delete = request.query_params.get('is_delete')
            process = request.query_params.get('process', '') # 退换货单处理方式
            is_changecode = request.query_params.get('is_changecode') # 改码状态过滤
            is_pickup = request.query_params.get('is_pickup') # 自提状态过滤
            user = request.query_params.get('user', '') # 用户过滤

            # 获取优化后的查询集
            queryset = self.get_queryset()
            initial_count = queryset.count()
            
            # 处理搜索
            if keyword and hasattr(self, 'search_field'):
                queryset = queryset.filter(**{f'{self.search_field}__icontains': keyword})
                after_keyword_count = queryset.count()
            
            # 处理删除状态
            if is_delete is not None and is_delete != '':
                is_delete = is_delete.lower() == 'true'
                queryset = queryset.filter(is_delete=is_delete)
            
            # 处理处理方式
            if process:
                queryset = queryset.filter(process=process)
            
            # 处理改码状态过滤
            if is_changecode is not None and is_changecode != '':
                is_changecode = is_changecode.lower() == 'true'
                queryset = queryset.filter(is_changecode=is_changecode)
            
            # 处理自提状态过滤
            if is_pickup is not None and is_pickup != '':
                is_pickup = is_pickup.lower() == 'true'
                queryset = queryset.filter(is_pickup=is_pickup)
            
            # 处理用户过滤
            if user:
                queryset = queryset.filter(created_by__username__icontains=user)
            
            # 使用分页
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response({
                    'code': 200,
                    'message': '获取成功',
                    'data': {
                        'items': serializer.data
                    }
                })
            
        except Exception as e:
            logger.error(f"获取订单列表失败: {str(e)}")
            return Response({
                'code': 500,
                'message': f'获取失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(methods=['PUT'], detail=False, url_path='update')
    def update_order(self, request, *args, **kwargs):
        """
        通用的订单更新方法（已优化查询性能）
        """
        try:
            data = request.data.copy()  
            lookup_field = 'id'
            lookup_value = data.get('id')
            
            if not lookup_value:
                return Response({'code': 400,'message': '缺少必要参数','error': f'未提供{lookup_field}'}, status=status.HTTP_400_BAD_REQUEST)
            
            # 查找对应的订单 - 使用优化后的查询集
            try:
                # 使用优化后的查询集，包含select_related
                order = self.get_optimized_queryset().get(**{lookup_field: lookup_value})
            except ObjectDoesNotExist:
                return Response({'code': 404,'message': '订单不存在','error': f'未找到{lookup_field}为{lookup_value}的订单'}, status=status.HTTP_404_NOT_FOUND)
            except Exception as e:
                logger.error(f"查询订单时发生错误: {str(e)}")
                return Response({'code': 500,'message': '查询订单失败','error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
            # 处理shipping_method字段
            if 'shipping_method' in data:
                shipping_method = data['shipping_method']
                if shipping_method == '黑猫':
                    data['shipping_method'] = 'YAMATO'
                elif shipping_method == '佐川':
                    data['shipping_method'] = 'SAGAWA'
            
            # 更新订单信息
            serializer = self.get_serializer(order, data=data, partial=True)
            if serializer.is_valid():
                # 手动处理create_time字段
                if 'create_time' in data and data['create_time']:
                    from datetime import datetime
                    try:
                        # 将日期字符串转换为datetime对象
                        create_time = datetime.strptime(data['create_time'], '%Y-%m-%d %H:%M:%S')
                        # 手动设置create_time
                        order.create_time = create_time
                    except ValueError:
                        return Response({
                            'code': 400,
                            'message': '更新失败',
                            'error': '创建时间格式错误，请使用 YYYY-MM-DD HH:MM:SS 格式'
                        }, status=status.HTTP_400_BAD_REQUEST)
                
                updated_order = serializer.save()
                # 如果手动修改了create_time，确保在保存后再次应用
                if 'create_time' in data and data['create_time']:
                    order.save()
                
                return Response({
                    'code': 200,
                    'message': '更新成功',
                    'data': self.get_serializer(order).data
                })
            else:
                return Response({
                    'code': 400,
                    'message': '更新失败',
                    'error': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)
                
        except Exception as e:
            logger.error(f"更新订单失败: {str(e)}")
            return Response({
                'code': 500,
                'message': '更新失败',
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
    @action(methods=['POST'], detail=False, url_path='delete_order')
    def delete_order(self, request, *args, **kwargs):
        """
        通用的订单删除方法（已优化查询性能）
        """
        try:
            # 获取请求数据
            data = request.data.copy()
            
            # 判断视图类型
            # self.__class__.__name__ == 'LocalOrderViewSet':
            lookup_field = 'id'
            lookup_value = data.get('id')
            
            if not lookup_value:
                return Response({
                    'code': 400,
                    'message': '缺少必要参数',
                    'error': f'未提供{lookup_field}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 查找对应的订单 - 使用优化后的查询集
            try:
                # 使用优化后的查询集，包含select_related
                order = self.get_optimized_queryset().get(**{lookup_field: lookup_value})
            except ObjectDoesNotExist:
                return Response({
                    'code': 404,
                    'message': '订单不存在',
                    'error': f'未找到{lookup_field}为{lookup_value}的订单'
                }, status=status.HTTP_404_NOT_FOUND)
            except Exception as e:
                # 处理其他异常
                logger.error(f"查询订单时发生错误: {str(e)}")
                return Response({
                    'code': 500,
                    'message': '查询订单失败',
                    'error': str(e)
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
            # 删除订单
            order.delete()
        
            return Response({
                'code': 200,
                'message': '删除成功'
            })
                
        except Exception as e:
            logger.error(f"删除订单失败: {str(e)}")
            return Response({
                'code': 500,
                'message': '删除失败',
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(methods=['POST'], detail=False, url_path='import')
    def import_orders(self, request, *args, **kwargs):
        """
        创建订单
        """
        try:
            # 获取请求数据
            data = request.data.copy()
            
            # 根据视图集类型创建对应的模型
            viewset_name = self.__class__.__name__
            if viewset_name == 'LocalOrderViewSet':
                model = LocalOrder
            elif viewset_name == 'TransferOrderViewSet':
                model = TransferOrder
            elif viewset_name == 'AfterSaleOrderViewSet':
                model = AfterSaleOrder
            elif viewset_name == 'RelocationOrderViewSet':
                model = RelocationOrder
            elif viewset_name == 'CrossOrderViewSet':
                model = CrossOrder
            elif viewset_name == 'InventoryReceiveOrderViewSet':
                model = InventoryReceiveOrder
            elif viewset_name == 'RepairOrderViewSet':
                model = RepairOrder
            elif viewset_name == 'ReturnOrderViewSet':
                model = ReturnOrder
            else:
                return Response({
                    'code': 400,
                    'message': f'不支持的订单类型: {viewset_name}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 创建订单
            order = model.objects.create(
                **data,
                created_by=request.user
            )
            
            return Response({       
                'code': 200,
                'message': '创建成功',
                'data': self.get_serializer(order).data
            })
            
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'创建失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)